/**
 * @project_name thread
 * @package_name com.gxwz.thread
 * @file_name Java5SpecificCallableInterface4Thread.java
 */
package com.gxwz.thread;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

/**
 * @author chendequan
 * @email 1527254027@qq.com
 * @datetime 2013-9-5 下午11:37:37
 * 
 */
public class Java5SpecificCallableInterface4Thread {
	// Callable接口功能类似于Runnable接口。她们都是规定了线程的执行任务。
	// Callable和Runnable的不同点：
	// 1. Callable规定要实现的方法是call()，Runnable规定要实现的方法是run()。
	// 2. Callable的任务执行后可有返回值，Runnable的任务时没有返回值的。
	// 3. call方法可以抛出异常，run方法不可以。
	// 4. 运行Callable任务可以拿到一个Future对象，该对象表示异步计算的run方法不行
	// 它提供了检查计算是否完成的方法，以等待计算完成，并检索计算的结果。通过Future对象
	// 可以了解任务执行情况，可以取消任务的执行，还可以获取执行结果。
	public static void main(String[] args) {
		ExecutorService singlePool = Executors.newSingleThreadExecutor();
//		Future 表示异步计算的结果。它提供了检查计算是否完成的方法，
//		以等待计算的完成，并获取计算的结果。
//		计算完成后只能使用 get 方法来获取结果，
//		如有必要，计算完成前可以阻塞此方法。
//		取消则由 cancel 方法来执行。
//		还提供了其他方法，以确定任务是正常完成还是被取消了。
//		一旦计算完成，就不能再取消计算。
//		如果为了可取消性而使用 Future 但又不提供可用的结果，
//		则可以声明 Future<?> 形式类型、并返回 null 作为底层任务的结果。 

//		提交一个有返回值的任务
		Future<String> future = singlePool.submit(new Callable<String>() {

//			一定要实现call方法
			@Override
			public String call() throws Exception {
				Thread.sleep(4000);  //睡眠4秒
				return "执行call方法的返回值";
			}
			
		});
		System.out.println("wait four seconds ...");
//		 isCancelled 如果在任务正常完成前将其取消，则返回 true。
		System.out.println(future.isCancelled());
//		如果任务已完成，则返回 true。
		System.out.println(future.isDone());
		try {
//			 get 如有必要，等待计算完成，然后获取其结果。
			System.out.println("the result is " + future.get());
		} catch (InterruptedException e) {
			e.printStackTrace();
		} catch (ExecutionException e) {
			e.printStackTrace();
		}
	}
}
